package com.palm.vue.compiler;

import javax.script.*;
import java.io.*;

/**
 * 把Vue模版编译为Js
 * 采用java中的js引擎，调用官方js编译器进行模板的编译，然后封装为符合requirejs要求的模块
 */
public class VueCompiler implements ICompiler {
    Invocable invocable;
    private int mode;
    public VueCompiler(int mode) {
        this.mode=mode;
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("js");
        invocable = (Invocable) engine;
        String compiler= read(VueCompiler.class.getResourceAsStream("/vue.compiler.js"));
        engine.put("jct",new JavaContext());

        try {
            engine.eval(compiler);
            //执行js中的编译代码，js编译上半部分为vue官方站的Compiler代码
            //engine.eval("if(golatob){atob=function(src){return jct.atob(src);}}");
            if(mode==4){
                Object atob= engine.getContext().getAttribute("atob");
                if(atob==null){
                    engine.eval("function atob(src){return jct.atob(src);}");
                }
                Object btoa= engine.getContext().getAttribute("btoa");
                if(btoa==null){
                    engine.eval("function btoa(src){return jct.btoa(src);}");
                }
                engine.eval(read(VueCompiler.class.getResourceAsStream("/uglifyjs.js")));

            }
            engine.eval(read(VueCompiler.class.getResourceAsStream("/compile.js")));
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }
    public String compile(InputStream in){
        String source=read(in);
        return compile(source);
    }
    public String compile(String source){
        try {
            String ret = (String) invocable.invokeFunction("compile", source,mode);
            return ret;
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }

    protected static String read(InputStream is){
        StringBuilder sb = new StringBuilder();
        try(Reader reader = new InputStreamReader(is,"utf-8")) {
            BufferedReader br = new BufferedReader(reader, 512);
            int value;
            while ((value = br.read()) != -1) {
                sb.append((char) value);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }
}
